package com.dingwen.treasure.kettle.controller;

import cn.hutool.core.util.StrUtil;
import com.dingwen.treasure.kettle.base.annotation.ReSubmit;
import com.dingwen.treasure.kettle.base.controller.BaseViewController;
import com.dingwen.treasure.kettle.base.valid.ValidGroup;
import com.dingwen.treasure.kettle.base.vo.PageData;
import com.dingwen.treasure.kettle.base.vo.Result;
import com.dingwen.treasure.kettle.base.vo.ResultGenerator;
import com.dingwen.treasure.kettle.dto.modify.TaskInfoDto;
import com.dingwen.treasure.kettle.dto.modify.TaskInfoStateDto;
import com.dingwen.treasure.kettle.dto.query.TaskInfoQueryDto;
import com.dingwen.treasure.kettle.service.TaskInfoService;
import com.dingwen.treasure.kettle.vo.TaskInfoVo;
import groovy.util.logging.Slf4j;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.quartz.CronExpression;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 　TaskController
 * 　@author dingwen
 * 　@date 2022/8/22
 */
@Api(tags = "任务API")
@RestController
@Slf4j
@RequestMapping("task")
public class TaskController implements BaseViewController {


    /**
     * 任务信息服务
     */
    @Resource
    private TaskInfoService taskInfoService;


    @ApiOperation(value = "刷新任务列表")
    @PostMapping("refresh")
    @ReSubmit(message = "操作过于频繁", isDeleteKey = false, time = 10)
    public void refresh() {
        taskInfoService.refresh();
    }


    @ApiOperation(value = "任务列表")
    @ApiImplicitParam(name = "taskInfoDto", value = "taskInfoDto")
    @PostMapping("page")
    public Result<PageData<TaskInfoVo>> page(@RequestBody @Validated TaskInfoQueryDto taskInfoQueryDto) {
        // TODO 分页优化
        return ResultGenerator.genPage(taskInfoService.getTaskInfoPage(taskInfoQueryDto));
    }


    @ApiOperation(value = "立即执行")
    @ApiImplicitParam(value = "任务Id", name = "taskId")
    @PostMapping("/execute/{taskId}")
    public void executeImmediately(@PathVariable("taskId") Long taskId) {
        taskInfoService.executeImmediately(taskId);
    }

    @ApiOperation(value = "添加一个周期任务")
    @ApiImplicitParam(value = "taskInfoDto", name = "taskInfoDto")
    @PostMapping()
    public Result<TaskInfoVo> addPeriodicTask(@RequestBody @Validated({ValidGroup.Save.class}) TaskInfoDto taskInfoDto) {
        Assert.isTrue(StrUtil.isBlank(taskInfoDto.getCronExpression())
                        || CronExpression.isValidExpression(taskInfoDto.getCronExpression()),
                "cron表达式错误");
        return success(taskInfoService.addPeriodicTask(taskInfoDto));
    }

    @ApiOperation(value = "修改任务")
    @ApiImplicitParam(value = "taskInfoDto", name = "taskInfoDto")
    @PutMapping()
    public void modifyTask(@RequestBody @Validated({ValidGroup.Modify.class}) TaskInfoDto taskInfoDto) {
        Assert.isTrue(StrUtil.isBlank(taskInfoDto.getCronExpression())
                        || CronExpression.isValidExpression(taskInfoDto.getCronExpression()),
                "cron表达式错误");
        taskInfoService.modifyTaskInfoByTaskId(taskInfoDto);
    }

    @ApiOperation(value = "删除任务")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(value = "任务Id", name = "taskId"),
                    @ApiImplicitParam(value = "任务类型：1一次性任务 2周期性任务", name = "taskType")
            }
    )
    @DeleteMapping("/{taskId}/{taskType}")
    public void removeTask(@PathVariable("taskId") Long taskId, @PathVariable("taskType") Integer taskType) {
        taskInfoService.removeTaskInfoByTaskId(taskId, taskType);
    }


    @ApiOperation(value = "获取所有正在执行中的周期任务")
    @GetMapping("periodic")
    public Result<List<Map<String, Object>>> getRunningPeriodicTaskAll() {
        return success(taskInfoService.getRunningPeriodicTaskAll());
    }

    @ApiOperation(value = "修改任务状态")
    @PutMapping("state")
    @ApiImplicitParam(value = "taskInfoState", name = "taskInfoState")
    public void modifyTaskState(@RequestBody @Validated TaskInfoStateDto taskInfoState) {
        taskInfoService.modifyTaskState(taskInfoState);
    }
}
